package com.ffcs.crmd.tsp.server.manager;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ffcs.crmd.tsp.common.constant.LoggerName;
import com.ffcs.crmd.tsp.core.util.RemotingUtil;
import com.ffcs.crmd.tsp.server.netty.client.ClientRegisterInfo;

import io.netty.channel.Channel;

/**
 * 
 * 功能说明:客户端管理类
 *
 * @author ZHONGFUHUA
 * 
 * @since 2.0.0-SNAPSHOT
 *
 */
public class ClientRemotingManager {
    
    /**
     * 日志
     */
    private final static Logger                           LOG                   = LoggerFactory.getLogger(LoggerName.RemotingLoggerName);
    
    /**
     * 通道失效超时时间
     */
    private  long                             channelExpiredTimeout = 1000 * 120;
    
    /**
     * 任务通道缓存
     */
    private  Map<Channel, ClientRegisterInfo> channelTable          = new ConcurrentHashMap<Channel, ClientRegisterInfo>();
    
    /**
     * 
     * 功能说明:注册任务端
     * 
     * @param channel 通道
     * @param clientChannelInfo 客户端注册信息
     */
    public void registerClient(Channel channel, ClientRegisterInfo clientChannelInfo) {
        ClientRegisterInfo clientChannelInfoFound = this.channelTable.put(channel, clientChannelInfo);
        if (clientChannelInfoFound == null) {
            LOG.info("SERVER-CLIENT: new channel register success - clientId[{}] channel[{}]",
                clientChannelInfo.getClientId(), channel);
        }
    }
    
    /**
     * 
     * 功能说明:扫描定时没有更新的通道，并关闭移除
     *
     */
    public void scanChannelTimeout() {
        Iterator<Entry<Channel, ClientRegisterInfo>> channelTableIt = channelTable.entrySet().iterator();
        while (channelTableIt.hasNext()) {
            Entry<Channel, ClientRegisterInfo> entry = channelTableIt.next();
            ClientRegisterInfo clientRegisterInfo = entry.getValue();
            Channel channel = entry.getKey();
            long diff = System.currentTimeMillis() - clientRegisterInfo.getLastUpdateTimestamp();
            if (diff > channelExpiredTimeout) {
                channelTableIt.remove();
                RemotingUtil.closeChannel(channel);
                LOG.warn(
                    "SERVER-CLIENT: scan timeout channel and remove success - clientId[{}] channel[{}]",
                    clientRegisterInfo.getClientId(), channel);
            }
        }
        
    }
    
    /**
     * 
     * 功能说明:执行关闭通道事件
     * 
     * @param channel 通道
     */
    public void channelCloseEvent(Channel channel) {
        if (channel != null) {
            ClientRegisterInfo taskChannelInfo = this.channelTable.remove(channel);
            if (taskChannelInfo == null) {
                LOG.info(
                    "SERVER-CLIENT: one channel close sucess but may has been remove - channel[{}]",
                    channel);
            } else {
                LOG.info(
                    "SERVER-CLIENT: one channel close sucess - channel[{}] channelInfo[{}]",
                    channel, taskChannelInfo);
            }
        }
    }
    

    /** 
     * 功能说明:获取通道表
     * 
     * @return 通道表
     */
    public Map<Channel, ClientRegisterInfo> getChannelTable() {
        return channelTable;
    }
    
}
